﻿using System.Web.UI;
using System.Web.UI.WebControls;
using System;
using System.Text;
using System.Collections.Generic;
using System.Web.UI.HtmlControls;
using Medianamik.Core;
using System.Xml.Linq;
using System.Linq;
using System.Web.Services;

namespace Medianamik.UI.Controls
{
    public class DomainCreator : BaseMedianamikControl, IMedianamikControl, INamingContainer
    {
        #region Fields

        private const string DOMAINBOX_PREFIX = "domainBox";

        private PlaceHolder phrDomains = new PlaceHolder();
        private Button btnAddDomain = new Button();

        #endregion

        #region Events

        #region Override

        protected override void CreateControlHierarchy(bool pUseDataSource)
        {
            Controls.Add(new LiteralControl("<div style='border: solid 1px black; padding: 10px 10px 10px 10px'>"));

            btnAddDomain.ID = "btnAdd";
            btnAddDomain.Text = "Add";
            btnAddDomain.Click += new EventHandler(btnAddDomain_Click);
            btnAddDomain.CausesValidation = false;
            Controls.Add(btnAddDomain);
            Controls.Add(phrDomains);

            if (pUseDataSource)
            {
                
                    XElement xml = null;

                    try
                    {
                        xml = XElement.Parse(DataSource.ToString());
                        IEnumerable<XElement> domains = xml.Descendants("domain");
                        int numberOfDomains = domains.Count();

                        for (int i = 0; i < numberOfDomains; i++)
                        {
                            AddDomain(phrDomains, i, domains.ElementAt(i));
                            if (i > 0)
                            {
                                NextId++;
                            }
                        }

                        if (numberOfDomains > 1)
                        {
                            SetLastDomain();
                        }
                    }
                    catch
                    {
                        AddDomain(phrDomains, 0);
                    }
                
            }
            else
            {
                for (int i = 0; i < NextId; i++)
                {
                    if (RemoveIds.IndexOf(i.ToString()) < 0)
                    {
                        AddDomain(phrDomains, i);
                    }
                }
            }

            Controls.Add(new LiteralControl("<br/></div>"));
        }

        /// <summary>
        /// Validation unique côté serveur
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        //protected override void ServerValidateUnique(object source, ServerValidateEventArgs args)
        //{
        //    //TODO
        //    throw new NotImplementedException();
        //}

        #endregion

        private void btnAddDomain_Click(object sender, EventArgs e)
        {
            EnsureChildControls();
            AddDomain(phrDomains, NextId);
            NextId++;
            SetLastDomain();
        }

        private void RemoveDomain(object sender, EventArgs e)
        {
            EnsureChildControls();
            Control domainBox = (Control)sender;
            RemoveIds.Add(domainBox.ID.Substring(domainBox.ID.LastIndexOf(DOMAINBOX_PREFIX) + DOMAINBOX_PREFIX.Length));
            phrDomains.Controls.Remove(domainBox);
            SetLastDomain();
        }

        #endregion

        #region Properties

        #region Override

        public override Type TypeOfValue
        {
            get { return typeof(string); }
        }

       public override object GetValue()
        {

                EnsureChildControls();

                XElement domains = new XElement("domains");

                foreach (Control control in phrDomains.Controls)
                {
                    if (control.GetType() == typeof(DomainBox))
                    {
                        if (((DomainBox)control).Value != null)
                        {
                            domains.Add(((DomainBox)control).Value);
                        }
                    }
                }

                return domains;
            

        }

        #endregion

        protected int NextId
        {
            get
            {
                if (ViewState["controlcount"] == null)
                {
                    ViewState["controlcount"] = 1;
                    return 1;
                }
                return (int)ViewState["controlcount"];
            }
            set
            {
                ViewState["controlcount"] = value;
            }
        }

        private List<String> _removedIds;
        public List<String> RemoveIds
        {
            get
            {
                if (_removedIds == null)
                {
                    if (!FromViewStateToStrings("RemoveIds", out _removedIds))
                    {
                        _removedIds = new List<string>();
                        ViewState["RemoveIds"] = _removedIds;
                    }
                }

                return _removedIds;
            }
            set
            {
                _removedIds = value;
                ViewState["RemoveIds"] = _removedIds;
            }
        }

        #endregion

        #region Methods

        private void SetLastDomain()
        {
            EnsureChildControls();

            foreach (Control control in phrDomains.Controls)
            {
                if (control.GetType() == typeof(DomainBox))
                {
                    ((DomainBox)control).IsLastDomain = IsLastDomain;
                }
            }
        }

        private bool IsLastDomain
        {
            get
            {
                return ((NextId - RemoveIds.Count) < 2);
            }
        }

        private void AddDomain(Control parent, int ctrlId)
        {
            AddDomain(parent, ctrlId, null);
        }

        private void AddDomain(Control parent, int ctrlId, XElement value)
        {
            DomainBox domainBox = new DomainBox();
            if (value != null)
            {
                domainBox.Value = value;
            }
            parent.Controls.Add(domainBox);
            domainBox.ID = ID + DOMAINBOX_PREFIX + ctrlId.ToString();
            //domainBox.Templates = Templates;
            domainBox.RemoveDomain += RemoveDomain;
            domainBox.IsLastDomain = IsLastDomain;

        }

        private bool FromViewStateToStrings(string key, out List<String> list)
        {
            bool result = true;

            list = new List<string>();

            if (ViewState[key] == null)
            {
                result = false;
            }
            else
            {
                try
                {
                    list = (List<String>)ViewState[key];
                }
                catch
                {
                    result = false;
                }
            }

            return result;
        }

        #endregion

        #region Inner Classes

        private class DomainBox : CompositeControl, INamingContainer
        {
            #region Fields

            TextBox txtDomain = new TextBox();
            Button btnRemoveDomain = new Button();

            #endregion

            #region Events

            protected override void CreateChildControls()
            {
                HtmlGenericControl br = new HtmlGenericControl("br");
                Controls.Add(br);

                txtDomain.ID = "txtDomain";
                Controls.Add(txtDomain);

                btnRemoveDomain.ID = ID + "btnRemoveDomain";
                btnRemoveDomain.Click += new EventHandler(btnRemoveDomain_Click);
                btnRemoveDomain.Text = "RemoveDomain";
                btnRemoveDomain.EnableViewState = false;
                btnRemoveDomain.CausesValidation = false;
                Controls.Add(btnRemoveDomain);

                if (_value != null && _value.ToString().Length > 0)
                {
                    EnsureChildControls();
                    txtDomain.Text = _value.Value;
                }
            }

            public event EventHandler RemoveDomain;
            private void btnRemoveDomain_Click(object sender, EventArgs e)
            {
                if (RemoveDomain != null)
                    RemoveDomain(this, e);
            }

            #endregion

            #region Properties

            private XElement _value;
            public XElement Value
            {
                get
                {
                    EnsureChildControls();

                    if (txtDomain.Text.Length > 0)
                    {
                        return new XElement("domain", txtDomain.Text);
                    }

                    return null;
                }
                set
                {
                    _value = value;
                }
            }

            public bool IsLastDomain
            {
                get
                {
                    EnsureChildControls();
                    return !btnRemoveDomain.Enabled;
                }
                set
                {
                    EnsureChildControls();
                    btnRemoveDomain.Enabled = !value;
                }
            }

            #endregion

            #region Methods

            private bool FromViewStateToStrings(string key, out List<String> list)
            {
                bool result = true;

                list = new List<string>();

                if (ViewState[key] == null)
                {
                    result = false;
                }
                else
                {
                    try
                    {
                        list = (List<String>)ViewState[key];
                    }
                    catch
                    {
                        result = false;
                    }
                }

                return result;
            }

            #endregion
        }

        #endregion
    }
}
